package com.rzjm.api.netty.water.business.inhandler;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.rzjm.api.entity.DeviceWater;
import com.rzjm.api.entity.DeviceWaterCard;
import com.rzjm.api.entity.DeviceWaterOrder;
import com.rzjm.api.netty.water.NettyUtil;
import com.rzjm.api.netty.water.entity.ReceiveData;
import com.rzjm.api.service.IDeviceWaterCardService;
import com.rzjm.api.service.IDeviceWaterMessagesService;
import com.rzjm.api.service.IDeviceWaterOrderService;
import com.rzjm.api.service.IDeviceWaterService;
import com.rzjm.api.util.*;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Optional;

import static com.rzjm.api.netty.water.constant.SendRtEnum.SEND_RT_2;

/**
 *  上传水卡信息
 * @author Mr.Zhou
 * @Description:
 * @date 2025/3/17 9:27
 */
@Component
public class Receive2InHandler implements InHandler {
    private static final Logger LOGGER = LoggerFactory.getLogger(Receive2InHandler.class);
    @Autowired
    private IDeviceWaterService devicesService;
    @Autowired
    private IDeviceWaterCardService waterCardService;
    @Autowired
    private IDeviceWaterMessagesService deviceMessagesService;
    @Autowired
    private IDeviceWaterOrderService waterOrderService;


    @Override
    public void handler(ChannelHandlerContext ctx, ReceiveData receiveData) {
        //保存Channel
        NettyUtil.addChannel(ctx, receiveData.getId());
        // 保存上报数据日志
        Optional.ofNullable(getMessage(receiveData))
                .ifPresent(message -> deviceMessagesService.save(message));

        DeviceWater deviceWater = devicesService.findById(receiveData.getId());
        if (deviceWater == null) {
            reply("{\"rt\":100,\"type\":2}", receiveData.getId());
        } else {
            //验证签名
            boolean bl = true;//validateSign(deviceWater, receiveData);
            if(bl){
                //回复消息
                String replyData = requestData(deviceWater, receiveData);
                if (StrUtil.isNotEmpty(replyData)) {
                    reply(replyData, receiveData.getId());
                }
            }else{
                reply("{\"rt\":100,\"type\":2}", receiveData.getId());
            }
        }
    }

    /**
     * 水卡信息 拼装数据
     * @param device
     * @param receiveData
     * @return
     */
    private String requestData(DeviceWater device, ReceiveData receiveData) {
        String replyData;
        System.out.println("刷卡数据上报请求：" + JSONUtil.toJsonStr(receiveData));
        JSONObject obj = JSONUtil.createObj();
        obj.set("rt", SEND_RT_2.getRt());
        obj.set("v1", receiveData.getV1());//水卡ID

        //加密算法 例如 ： id=1&v1=1&v2=2
//        String content = "id=" + receiveData.getId() + "&v1=" + receiveData.getV1();

        String crcV2 = "02";
        String crcMoney = "";
        String crcTimespan = "";
        DeviceWaterCard waterCard = waterCardService.getWaterCardByIcId(receiveData.getV1());
        if(waterCard != null){
            //卡号相同
            if(waterCard.getCardNum().equals(receiveData.getV2())){
                if(waterCard.getAccountMoney().doubleValue() <= 0
                        || waterCard.getAccountMoney().doubleValue() < device.getSinglePrice().doubleValue()){
                    // 余额不足
                    int money = (int)(waterCard.getAccountMoney().doubleValue() * 100);
                    if(money < 0){
                        money = 0;
                    }
                    obj.set("v3", money);//剩余金额
                    obj.set("v2", 5);//卡片状态 5 余额不足
                    obj.set("v4", "0");//订单号
                    obj.set("v5", 0);//单次出水量
                    obj.set("v6", 0);//单次出水价格
                    crcMoney = ByteUtil.int2Hex(0);
                    if(crcMoney.length() % 2 == 1){
                        crcMoney = "0" + crcMoney;
                    }
                }else{
                    //卡片状态  0 - 未激活  1 - 已激活可用  2 - 挂失  3 - 损坏 4 - 卡不存在  5 - 余额不足  6 - 无效卡
                    obj.set("v2", waterCard.getState());
                    int money = (int)(waterCard.getAccountMoney().doubleValue() * 100);
                    if(money < 0){
                        money = 0;
                    }
                    obj.set("v3", money);//剩余金额
//            content += "&v2=" + waterCard.getState() + "&v3=" + StringUtil.yuanToCent(waterCard.getAccountMoney().doubleValue()+"");
                    String moneyStr = money +"";
                    System.out.println("金额：" + moneyStr);
                    crcMoney = ByteUtil.int2Hex(Integer.parseInt(moneyStr.substring(moneyStr.length() - 2, moneyStr.length())));
                    if(crcMoney.length() % 2 == 1){
                        crcMoney = "0" + crcMoney;
                    }
                    DeviceWaterOrder order = waterOrderService.addOrderByCard(device, waterCard);
                    if(order != null){
                        obj.set("v4", order.getOrderNo());//订单号
                    }else{
                        obj.set("v4", "00000000");//生成订单异常
                    }

                    /**
                     * 单次打水的容量体积（L）
                     */
                    obj.set("v5", device.getSingleVolume().doubleValue() * 1000);//单次出水量
                    obj.set("v6", device.getSinglePrice().doubleValue() * 100);//单次出水价格
                }
            }else{
                //无效卡，数据库里存的卡号和ic卡id 不一样
                //卡片状态  0 - 未激活  1 - 已激活可用  2 - 挂失  3 - 损坏 4 - 卡不存在  5 - 余额不足  6 - 无效卡
                obj.set("v2", 6);//卡片状态  6 - 无效卡
                obj.set("v3", 0);//剩余金额
                obj.set("v4", "0");//订单号
                obj.set("v5", 0);//单次出水量
                obj.set("v6", 0);//单次出水价格
//                content += "&v2=4";
                crcMoney = ByteUtil.int2Hex(0);
                if(crcMoney.length() % 2 == 1){
                    crcMoney = "0" + crcMoney;
                }
            }
        }else{
            obj.set("v2", 4);//卡片状态 4 卡片不存在
            obj.set("v3", 0);//剩余金额
            obj.set("v4", "0");//订单号
            obj.set("v5", 0);//单次出水量
            obj.set("v6", 0);//单次出水价格
//            content += "&v2=4";
            crcMoney = ByteUtil.int2Hex(0);
            if(crcMoney.length() % 2 == 1){
                crcMoney = "0" + crcMoney;
            }
        }

        String timespan = String.valueOf(new Date().getTime());
        obj.set("v7", timespan);//时间戳

        System.out.println("时间戳 = " + timespan);
        crcTimespan = ByteUtil.int2Hex(Integer.parseInt(timespan.substring(timespan.length() - 2, timespan.length())));
        if(crcTimespan.length() % 2 == 1){
            crcTimespan = "0" + crcTimespan;
        }
        //crc 校验
        System.out.println("crcV2 = " + crcV2);
        System.out.println("crcMoney = " + crcMoney);
        System.out.println("crcTimespan = " + crcTimespan);

        String crc = getSignCrc(crcV2, crcMoney, crcTimespan);
        System.out.println("crc = " + crc);
        obj.set("v8", crc);//crc校验
        obj.set("v9", ByteUtil.getIntByHex(crc));//crc校验  10进制

        replyData = JSONUtil.toJsonStr(obj);
        return replyData;
    }


    /**
     * 获取签名 crc校验
     * @param v2
     * @param money
     * @param timespan
     * @return
     */
    private String getSignCrc(String v2, String money, String timespan){
        //低位在前，CRC校验3个字节，RT+剩余金额后两位+时间戳后两位
//        例：RT：02
//        金额：91=0x5B
//        时间戳64=0x40
//        结果：EAC0
        String crcData = v2 + money + timespan;
        System.out.println("校验串：" + crcData);
        String crc = CRCUtil.getCrc(crcData);
        return crc;
    }
}
